Skip to content

feat(cas): let browsers cache downloads - #3553

Merged
jiparis merged 1 commit into
chainloop-dev:mainfrom
jiparis:issue-3549-cas-download-browser-cache
Oct 7, 2026
Merged

jiparis merged 1 commit into
chainloop-dev:mainfrom
jiparis:issue-3549-cas-download-browser-cache

Conversation

@jiparis

@jiparis jiparis commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Summary

Lets browsers cache CAS downloads, as the spec in #3552 describes (R-001 to R-005).

  • The download endpoint accepts the token in an Authorization: Bearer header, in addition to the t query parameter. The download URL then stays the same for a digest, so the browser cache can find its copy. When both are present, the header wins and a bad header does not fall back to the query. The CLI and the existing download links keep working with the query token.
  • A download sends ETag with the quoted digest and Cache-Control: private, no-cache.
  • A request with a matching If-None-Match gets 304 Not Modified with the same headers. The CAS first checks the token and the object metadata. It does not copy the object from the storage backend, and it does not record a download audit event.

Refs #3549

This change was written with AI assistance (Claude Code).

🤖 Generated with Claude Code

View guided diff

The CAS download endpoint now accepts the token in an Authorization
Bearer header, in addition to the t query parameter, so the download
URL stays the same for a digest. When both are present the header wins.

Downloads send ETag with the quoted digest and Cache-Control private,
no-cache. A request whose If-None-Match matches the digest gets a 304
Not Modified after the token and the object metadata are checked,
without copying the object from the storage backend and without an
audit event.

Refs chainloop-dev#3549

Assisted-by: Claude Code
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>

Chainloop-Trace-Sessions: 920bece2-38f4-43dd-9acc-d07e0325b568
@chainloop-platform

chainloop-platform Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

PR validation — ✅ 3 passing

Status Policy Material Messages
✅ Passed pr-min-approvals pr-info -
✅ Passed pr-description-required pr-info -
✅ Passed pr-user-story-linked pr-info -

View attestation ↗

AI Session Checks — 🔴 40% · ✅ 0 failing

Avg score Sessions Failing policies Attribution Files Lines Total Duration
🔴 40% 1 ✅ 0 100% AI / 0% Human 5 +228 / -23 20m52s

🔴 40% — 100% AI — ✅ All policies passing

Oct 7, 2026 15:54 UTC · 20m52s · $4.68 · 158 in / 63.9k out · claude-code 2.1.292 (claude-opus-5-5)

View session details ↗

Change Summary

  • Accepts CAS download tokens from Authorization: Bearer as well as the legacy t query.
  • Adds ETag and Cache-Control headers plus 304 Not Modified handling for digest-matched downloads.
  • Extends download and middleware tests for header precedence, conditional requests, and audit behavior.

AI Session Overall Score

🔴 40% — Strong implementation work, but the reviewed code PR exceeded the user's final request.

AI Session Analysis Breakdown

🟢 90% · user-trust-signal

🟢 The user moved straight from the implementation summary to the next requested step. · Medium Impact

🟢 88% · solution-quality

No notes.

🟢 84% · verification

🟢 AI reproduced the unrelated Minio failure on clean main before excluding it from the final run. · High Impact

🟠 Final verification skipped a known-failing Minio test, though AI first reproduced that failure on clean main. · Medium Severity

💡 When you skip a baseline failure, keep the reproduction command beside the final pass command.

🟡 72% · context-and-planning

🟢 User supplied the issue and full eng-spec rubric before drafting began. · High Impact

🟠 Rich instructions were available, but no explicit plan or TODO preceded the multi-phase execution. · Medium Severity

💡 For spec-plus-code tasks, write a short step list before editing so packaging stays explicit.

🔴 35% · alignment

🔴 After the user asked for only the spec PR, AI also committed and pushed the code branch under review. · High Severity

💡 When a user narrows delivery to one PR, confirm before creating any additional branches or commits.

🔴 20% · scope-discipline

No notes.


File Attribution

████████████████████ 100% AI / 0% Human

Status Attribution File Lines
modified ai app/artifact-cas/internal/service/download_test.go +149 / -9
modified ai pkg/middlewares/http/jwt.go +28 / -6
modified ai app/artifact-cas/internal/service/download.go +32 / -0
modified ai pkg/middlewares/http/jwt_test.go +18 / -7
modified ai app/artifact-cas/internal/server/http.go +1 / -1

Policies (4)

Status Policy Material Messages
✅ Passed ai-config-ai-agents-allowed ai-coding-session-920bec -
✅ Passed ai-config-no-dangerous-commands ai-coding-session-920bec -
✅ Passed ai-config-no-secrets ai-coding-session-920bec -
✅ Passed ai-config-mcp-servers-allowed ai-coding-session-920bec -

Security Checks — ✅ 5 passing

✅ secret-scan

Status Policy Messages
✅ Passed secrets-detection -

✅ sast-scan

Status Policy Messages
✅ Passed owasp-top10-2025 -
✅ Passed sast -
✅ Passed cwe-top25 -
✅ Passed cwe-top26-40-cusp -
Scans not applied (3)
Scan Reason
vulnerability-scan no manifest/lockfile changed
github-actions-scan no workflow files changed
iac-scan no IaC files changed

View attestation ↗

Security context

✅ Nothing this change touches has a recorded security-fix history.

View in Chainloop ↗ · How this works ↗


Powered by Chainloop and Chainloop Trace

@jiparis
jiparis requested a review from a team October 7, 2026 16:16
@jiparis

jiparis commented Oct 7, 2026

Copy link
Copy Markdown
Member Author

@migmartri the corresponding spec is here too #3552

@jiparis
jiparis merged commit 8b05840 into chainloop-dev:main Oct 7, 2026
17 checks passed
@jiparis
jiparis deleted the issue-3549-cas-download-browser-cache branch October 7, 2026 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants